package com.xmhmyh.generalframework.project.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.Update;
import com.xmhmyh.generalframework.common.BaseServiceImpl;
import com.xmhmyh.generalframework.common.constants.Constants;
import com.xmhmyh.generalframework.common.enums.ResponseCode;
import com.xmhmyh.generalframework.common.utils.MyBeanUtils;
import com.xmhmyh.generalframework.framework.exceptions.ManageExceptions;
import com.xmhmyh.generalframework.project.sys.dto.ParamsDTO;
import com.xmhmyh.generalframework.project.sys.entity.Account;
import com.xmhmyh.generalframework.project.sys.entity.Params;
import com.xmhmyh.generalframework.project.sys.entity.User;
import com.xmhmyh.generalframework.project.sys.enums.ParamsAccountType;
import com.xmhmyh.generalframework.project.sys.enums.ParamsType;
import com.xmhmyh.generalframework.project.sys.mapper.ParamsMapper;
import com.xmhmyh.generalframework.project.sys.service.IAccountService;
import com.xmhmyh.generalframework.project.sys.service.IParamsService;
import jodd.cli.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: 于丁
 * @DateTime: 2020/7/24 9:09 上午
 */
@Service
public class ParamsServiceImpl extends BaseServiceImpl<ParamsMapper, Params> implements IParamsService {

    @Autowired
    private IAccountService accountService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveHandler(User user, ParamsDTO paramsDTO) {
        Params params = new Params();
        BeanUtils.copyProperties(paramsDTO, params);
        if (params.getType() == ParamsType.OPT.getValue()) {
            if (!user.getAccountId().equals(Constants.SUPER_ACCOUNT_ID)) {
                throw new ManageExceptions(ResponseCode.OPT_PARAMS_NOT_EDIT);
            }
        }
        if (paramsDTO.getId() == null) {
            if (!checkCodeIsRepeat(params.getCode(), null, user.getAccountId())) {
                throw new ManageExceptions(ResponseCode.CODE_REPEAT);
            }
            MyBeanUtils.setSysInfo(params, user.getId(), user.getAccountId());
            save(params);
            if (user.getAccountId() == Constants.SUPER_ACCOUNT_ID) {
                syncCreateParams(params);
            }
        } else {
            if (!checkCodeIsRepeat(params.getCode(), params.getId(), user.getAccountId())) {
                throw new ManageExceptions(ResponseCode.CODE_REPEAT);
            }
            Params old = getById(paramsDTO.getId());
            if (old == null) {
                throw new ManageExceptions(ResponseCode.ENTITY_NOT_FIND);
            }
            MyBeanUtils.updateSysInfo(params, user.getId());
            params.setId(old.getId());
            params.setCreateBy(old.getCreateBy());
            params.setEnabled(old.getEnabled());
            params.setCreateTime(old.getCreateTime());
            updateById(params);
            if (user.getAccountId() == Constants.SUPER_ACCOUNT_ID) {
                syncEditParams(params);
            }

        }
    }

    /**
     * @Author: 于丁
     * @Description: 检测code是否重复
     * @DateTime: 2020/10/10 4:14 下午
     * @Params: * @param: null
     * @Return false 重复 true 不重复
     */
    public boolean checkCodeIsRepeat(String code, Long paramsId, Long accountId) {
        LambdaQueryWrapper<Params> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Params::getCode, code);
        queryWrapper.eq(Params::getAccountId, accountId);
        if (paramsId != null) {
            queryWrapper.ne(Params::getId, paramsId);
        }
        return count(queryWrapper) > 0 ? false : true;
    }

    /**
     * @Author: 于丁
     * @Description:
     * @DateTime: 批量修改 4:44 下午
     * @Params: * @param: null
     * @Return {@link null}
     */
    public void syncEditParams(Params params) {
        // 账户级别的不需要同步
        if (params.getType() == ParamsType.ACCOUNT.getValue()) {
            return;
        }
        LambdaUpdateWrapper<Params> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Params::getCode, params.getCode());
        updateWrapper.ne(Params::getId, params.getId());
        updateWrapper.set(Params::getValue, params.getValue());
        updateWrapper.set(Params::getRemark, params.getRemark());
        update(updateWrapper);
    }

    /**
     * @Author: 于丁
     * @Description: 同步创建系统参数
     * @DateTime: 2020/10/10 4:13 下午
     * @Params: * @param: null
     * @Return {@link null}
     */
    public void syncCreateParams(Params params) {
        // 需要同步的账户
        List<Account> accountList = new ArrayList<>();
        // 判断params类型
        accountList = accountService.list();
        List<Params> paramsList = new ArrayList<>();
        for (Account account : accountList) {
            Params p = params.baseClone();
            p.setId(uidGenerator.getUID());
            MyBeanUtils.setSysInfo(p, account.getAdminUserId(), account.getId());
            paramsList.add(p);
        }
        saveBatch(paramsList);
    }

    @Override
    public Params getByCode(String code, Long accountId) {
        LambdaQueryWrapper<Params> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Params::getCode, code);
        queryWrapper.eq(Params::getAccountId, accountId);
        Params params = getOne(queryWrapper);
        return params;
    }

    @Override
    public void removeByCode(String code) {
        LambdaQueryWrapper<Params> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Params::getCode, code);
        remove(queryWrapper);
    }
}
